import { MonthlyPaymentInfo, MortgageLoanForm } from "./interface";

// 提取等额本息计算逻辑
function calculateEqualPrincipalAndInterest(loanAmount: number, monthlyInterestRate: number, totalMonths: number) {
  const monthlyPayment = (loanAmount * monthlyInterestRate * Math.pow(1 + monthlyInterestRate, totalMonths)) /
    (Math.pow(1 + monthlyInterestRate, totalMonths) - 1);
  const paymentInfoList = [];
  let remainingPrincipal = loanAmount;
  for (let i = 0; i < totalMonths; i++) {
    const interestRepayment = remainingPrincipal * monthlyInterestRate;
    const principalRepayment = monthlyPayment - interestRepayment;
    remainingPrincipal -= principalRepayment;
    paymentInfoList.push(new MonthlyPaymentInfo(monthlyPayment, principalRepayment, interestRepayment, remainingPrincipal));
  }
  return paymentInfoList;
}

// 提取等额本金计算逻辑
function calculateEqualPrincipal(loanAmount: number, monthlyInterestRate: number, totalMonths: number) {
  const principalRepayment = loanAmount / totalMonths;
  const paymentInfoList = [];
  let remainingPrincipal = loanAmount;
  for (let i = 0; i < totalMonths; i++) {
    const interestRepayment = remainingPrincipal * monthlyInterestRate;
    const monthlyPayment = principalRepayment + interestRepayment;
    remainingPrincipal -= principalRepayment;
    paymentInfoList.push(new MonthlyPaymentInfo(monthlyPayment, principalRepayment, interestRepayment, remainingPrincipal));
  }
  return paymentInfoList;
}

/**
 * 计算商业房贷还款信息
 * @param {number} loanAmount - 贷款金额
 * @param {number} loanYears - 贷款年限
 * @param {InterestRateType} interestRateType - 利率方式
 * @param {number} [lprRate] - LPR 利率
 * @param {number} [basisPoints] - 基点
 * @param {CalculationMethod} calculationMethod - 计算方式
 * @returns {MonthlyPaymentInfo[]} - 每月还款信息数组
 */
export function calculateMortgagePayment(mortgageLoanForm: MortgageLoanForm) {
  const {
    loanAmount, loanYears, interestRateType, lprRate, basisPoints, calculationMethod
  } = mortgageLoanForm;

  const totalMonths = loanYears * 12;
  let monthlyInterestRate;
  if (interestRateType === 'LPR') {
    monthlyInterestRate = (lprRate + basisPoints / 10000) / 12;
  } else {
    // 这里可以根据基准利率的逻辑进行处理，暂时简化为 0
    monthlyInterestRate = 0;
  }

  if (calculationMethod === 'EqualPrincipalAndInterest') {
    return calculateEqualPrincipalAndInterest(loanAmount, monthlyInterestRate, totalMonths);
  } else if (calculationMethod === 'EqualPrincipal') {
    return calculateEqualPrincipal(loanAmount, monthlyInterestRate, totalMonths);
  }
  return [];
}

/**
 * 计算公积金贷款还款信息（等额本息）
 * @param {number} providentFundLoanAmount - 公积金贷款金额
 * @param {number} providentFundInterestRate - 公积金贷款利率（年利率）
 * @param {number} loanYears - 贷款年限
 * @returns {MonthlyPaymentInfo[]} - 每月还款信息数组
 */
export function calculateProvidentFundLoan(mortgageLoanForm: MortgageLoanForm) {
  const { providentFundLoanAmount, providentFundInterestRate, loanYears, calculationMethod } = mortgageLoanForm;
  const totalMonths = loanYears * 12;
  const monthlyInterestRate = providentFundInterestRate / 12;

  if (calculationMethod === 'EqualPrincipalAndInterest') {
    return calculateEqualPrincipalAndInterest(providentFundLoanAmount, monthlyInterestRate, totalMonths);
  } else if (calculationMethod === 'EqualPrincipal') {
    return calculateEqualPrincipal(providentFundLoanAmount, monthlyInterestRate, totalMonths);
  }
  return [];
}

/**
 * 计算组合贷款还款信息（包含公积金和商业贷款）
 * @param {MortgageLoanForm} mortgageLoanForm - 贷款表单信息
 * @returns {MonthlyPaymentInfo[]} - 每月还款信息数组
 */
export function calculateCombinedLoan(mortgageLoanForm: MortgageLoanForm) {
  const commercialPaymentInfo = calculateMortgagePayment(mortgageLoanForm);
  const providentFundPaymentInfo = calculateProvidentFundLoan(mortgageLoanForm);

  const combinedPaymentInfo: MonthlyPaymentInfo[] = [];
  for (let i = 0; i < commercialPaymentInfo.length; i++) {
    const commercial = commercialPaymentInfo[i];
    const providentFund = providentFundPaymentInfo[i];

    const totalMonthlyPayment = commercial.monthlyPayment + providentFund.monthlyPayment;
    const totalPrincipalRepayment = commercial.principalRepayment + providentFund.principalRepayment;
    const totalInterestRepayment = commercial.interestRepayment + providentFund.interestRepayment;
    const totalRemainingPrincipal = commercial.remainingPrincipal + providentFund.remainingPrincipal;

    combinedPaymentInfo.push(new MonthlyPaymentInfo(totalMonthlyPayment, totalPrincipalRepayment, totalInterestRepayment, totalRemainingPrincipal));
  }

  return combinedPaymentInfo;
}